/** @file main.cpp
  * @version svn
  * @author Jajec, endrju.
  *
  * Glowny plik projektu.
  * WIPS - Wips is physic simulator
  * Dokumentacja zostanie uzupelniona, kiedy ustali sie ostateczna struktura kodu!
  * @todo Uzupelnic i poprawic dokumentacje Doxygen.
  */

#include "header.h"

using namespace std;

unsigned int t10ms = 1;

inline void timer10ms() {
  t10ms++;
}

/** @fn float calculateDeltaT()
  * @return Delta T
  * @brief Oblicza aktualna wartosc skoku czasu.
  */
float calculateDeltaT() {
  static unsigned int dt1=0;
  static float df=0.01;
  float f=(t10ms-dt1)*0.01f;

  f=(f+df)/2.0;
  df=f;
  dt1=t10ms;

  return f;
}

int main(){
  const unsigned int SW = 800, SH = 600; ///< Wysokosc, szerokosc
  enum{
    kolka,
    wielokaty,
    bomby
  } coSieDzieje=bomby;

  MyAllegro screen(SW, SH);
  install_int(timer10ms, 10);

  vector<Circle*> tabCircle;
  vector<Poly*> tabPoly;
  Vector2 bomb;
  float dt;
  bool doGravity=true;

  /*const int size=10;
  for(int i=100;i<700;i+=size*3)
    for(int j=100;j<300;j+=size*3)
      tabCircle.push_back(new Circle(Vector2(i,j),size, makecol(250,250,250)));//*/

  tabCircle.push_back(new Circle(Vector2(SW/2, SH-100), 99, screen.cWhite()));
  tabCircle.push_back(new Circle(Vector2(SW/2+2, SH-110), 9, screen.cWhite()));
  tabCircle[tabCircle.size()-1]->omega = 1.5;//*/



  do{
    poll_mouse();
    poll_keyboard();
    clear_to_color(screen.getBuffer(), makecol(SBG_COLOR.R, SBG_COLOR.G, SBG_COLOR.B));

    /// obsluga klawiatury
    /// @todo obsluga klawiatury powinna wyladowac w osobnym pliku/klasie tak jak myszka
    if(key[KEY_B]) coSieDzieje = bomby;
    else if(key[KEY_K]) coSieDzieje = kolka;
    else if(key[KEY_W]) coSieDzieje = wielokaty;
    else if(key[KEY_G] && key[KEY_N]) doGravity = true;
    else if(key[KEY_G] && key[KEY_F]) doGravity = false;
    else if(key[KEY_R])
      if(tabPoly.size() > 0)
        tabPoly.clear();

    /// obsluga myszki
    if(coSieDzieje==kolka){
      Circle *c=mCircle(screen);
      if(c!=0) tabCircle.push_back(c);
    }
    else if(coSieDzieje==wielokaty) {
      Poly *p=mPoly(screen);
      if(p!=0) tabPoly.push_back(p);
    }
    else if(coSieDzieje==bomby) {
      mBombs(tabCircle);
    }

    dt = calculateDeltaT();

    int s = tabCircle.size();

    for(int i=0; i < s; i++)
      tabCircle[i]->deltaT(dt, SW, SH, doGravity);

    /// @todo Petla kolizji chyba powinna byc jakas inna...
    for(int i=0; i < (s-1); i++) {
      for(int j=i+1 ; j < s; j++) {
        tabCircle[i]->collision(*(tabCircle[j]));
      }
    }

    /// @todo Obsluga zderzen i przesuniec polygonow!!!

    for(unsigned int i=0; i < tabCircle.size(); i++)
      tabCircle[i]->render(screen.getBuffer());
    for(unsigned int i=0; i < tabPoly.size(); i++)
      tabPoly[i]->render(screen.getBuffer());

    textprintf_ex(screen.getBuffer(), font, 10, 10, screen.cWhite(), screen.cBlack(),
      "t10ms: %d; dt: %f",t10ms, dt);
    textprintf_ex(screen.getBuffer(), font, 10, 20, screen.cWhite(), screen.cBlack(),
      "coSieDzieje (0 (K)olka, 1 (W)ielokaty, 2 (B)omby): %d",static_cast<int>(coSieDzieje));
    textprintf_ex(screen.getBuffer(), font, 10, 30, screen.cWhite(), screen.cBlack(),
      "(R) usun wielokaty, (G) grawitacja o(n) / o(f)f : %s", doGravity?"on":"off");
    screen.drawCursor();
    screen.doubleBuffering();

  } while (!key[KEY_ESC]);


  for(unsigned int i = 0; i < tabCircle.size(); i++)
    delete tabCircle[i];
  for(unsigned int i = 0; i < tabPoly.size(); i++)
    delete tabPoly[i];

  return 0;
}

END_OF_MAIN()
